<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>M3U播放列表管理器</title>
    <script src="https://cdn.tailwindcss.com"></script>
    <link href="https://cdn.jsdelivr.net/npm/font-awesome@4.7.0/css/font-awesome.min.css" rel="stylesheet">
    <script>
        tailwind.config = {
            theme: {
                extend: {
                    colors: {
                        primary: '#3B82F6',
                        secondary: '#10B981',
                        dark: '#1E293B',
                        light: '#F8FAFC',
                        accent: '#8B5CF6'
                    },
                    fontFamily: {
                        sans: ['Inter', 'system-ui', 'sans-serif'],
                    },
                }
            }
        }
    </script>
    <style type="text/tailwindcss">
        @layer utilities {
            .content-auto {
                content-visibility: auto;
            }
            .scrollbar-hide {
                -ms-overflow-style: none;
                scrollbar-width: none;
            }
            .scrollbar-hide::-webkit-scrollbar {
                display: none;
            }
            .text-shadow {
                text-shadow: 0 2px 4px rgba(0,0,0,0.1);
            }
            .transition-height {
                transition: max-height 0.3s ease-in-out;
            }
        }
    </style>
</head>
<body class="bg-gray-50 text-gray-800 min-h-screen flex flex-col">
    <!-- 顶部导航栏 -->
    <header class="bg-white shadow-md sticky top-0 z-50 transition-all duration-300">
        <div class="container mx-auto px-4 py-3 flex justify-between items-center">
            <div class="flex items-center space-x-2">
                <i class="fa fa-play-circle text-primary text-2xl"></i>
                <h1 class="text-xl md:text-2xl font-bold text-gray-800">M3U播放列表管理器</h1>
            </div>
            <div class="flex items-center space-x-4">
                <button id="helpBtn" class="text-gray-600 hover:text-primary transition-colors">
                    <i class="fa fa-question-circle mr-1"></i>帮助
                </button>
                <button id="themeToggle" class="text-gray-600 hover:text-primary transition-colors">
                    <i class="fa fa-moon-o"></i>
                </button>
            </div>
        </div>
    </header>

    <!-- 主内容区 -->
    <main class="flex-grow container mx-auto px-4 py-6">
        <!-- 步骤指示器 -->
        <div class="mb-8">
            <div class="flex items-center justify-between max-w-3xl mx-auto">
                <div class="flex flex-col items-center">
                    <div id="step1Icon" class="w-10 h-10 rounded-full bg-primary text-white flex items-center justify-center mb-2">
                        <i class="fa fa-upload"></i>
                    </div>
                    <span class="text-sm font-medium text-primary">上传文件</span>
                </div>
                <div class="flex-1 h-1 mx-2 bg-gray-200">
                    <div id="progress1" class="h-full bg-primary w-0 transition-all duration-500"></div>
                </div>
                <div class="flex flex-col items-center">
                    <div id="step2Icon" class="w-10 h-10 rounded-full bg-gray-200 text-gray-600 flex items-center justify-center mb-2">
                        <i class="fa fa-cogs"></i>
                    </div>
                    <span class="text-sm font-medium text-gray-500">处理列表</span>
                </div>
                <div class="flex-1 h-1 mx-2 bg-gray-200">
                    <div id="progress2" class="h-full bg-primary w-0 transition-all duration-500"></div>
                </div>
                <div class="flex flex-col items-center">
                    <div id="step3Icon" class="w-10 h-10 rounded-full bg-gray-200 text-gray-600 flex items-center justify-center mb-2">
                        <i class="fa fa-list"></i>
                    </div>
                    <span class="text-sm font-medium text-gray-500">分组管理</span>
                </div>
                <div class="flex-1 h-1 mx-2 bg-gray-200">
                    <div id="progress3" class="h-full bg-primary w-0 transition-all duration-500"></div>
                </div>
                <div class="flex flex-col items-center">
                    <div id="step4Icon" class="w-10 h-10 rounded-full bg-gray-200 text-gray-600 flex items-center justify-center mb-2">
                        <i class="fa fa-download"></i>
                    </div>
                    <span class="text-sm font-medium text-gray-500">导出结果</span>
                </div>
            </div>
        </div>

        <!-- 步骤1: 文件上传区域 -->
        <section id="step1" class="mb-8">
            <div class="bg-white rounded-xl shadow-lg p-6 md:p-8 transition-all duration-300 hover:shadow-xl">
                <h2 class="text-xl md:text-2xl font-bold mb-6 text-gray-800 flex items-center">
                    <i class="fa fa-upload text-primary mr-2"></i>上传M3U文件
                </h2>
                
                <div id="dropArea" class="border-2 border-dashed border-gray-300 rounded-lg p-8 text-center mb-6 transition-all duration-300 hover:border-primary hover:bg-blue-50">
                    <i class="fa fa-file-text-o text-5xl text-gray-400 mb-4"></i>
                    <p class="mb-2 text-gray-600">拖放M3U文件到此处，或</p>
                    <label class="inline-block bg-primary hover:bg-primary/90 text-white font-medium py-2 px-6 rounded-lg cursor-pointer transition-all duration-300 transform hover:scale-105">
                        <i class="fa fa-folder-open mr-1"></i>选择文件
                        <input type="file" id="fileInput" accept=".m3u,.m3u8" multiple class="hidden">
                    </label>
                    <p class="mt-4 text-sm text-gray-500">支持同时上传多个M3U/M3U8文件</p>
                </div>
                
                <div id="fileList" class="mb-6 max-h-40 overflow-y-auto scrollbar-hide border rounded-lg p-4 hidden">
                    <h3 class="font-medium text-gray-700 mb-2">已选择文件:</h3>
                    <ul id="selectedFiles" class="space-y-2"></ul>
                </div>
                
                <div class="flex justify-end">
                    <button id="processBtn" class="bg-primary hover:bg-primary/90 text-white font-medium py-2 px-6 rounded-lg transition-all duration-300 transform hover:scale-105 disabled:opacity-50 disabled:cursor-not-allowed disabled:hover:scale-100" disabled>
                        <i class="fa fa-arrow-right mr-1"></i>开始处理
                    </button>
                </div>
            </div>
        </section>

        <!-- 步骤2: 处理列表 -->
        <section id="step2" class="mb-8 hidden">
            <div class="bg-white rounded-xl shadow-lg p-6 md:p-8 transition-all duration-300 hover:shadow-xl">
                <h2 class="text-xl md:text-2xl font-bold mb-6 text-gray-800 flex items-center">
                    <i class="fa fa-cogs text-primary mr-2"></i>处理播放列表
                </h2>
                
                <div class="mb-6">
                    <h3 class="font-medium text-gray-700 mb-3">处理选项</h3>
                    <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
                        <div class="flex items-center">
                            <input type="checkbox" id="removeDuplicates" checked class="w-4 h-4 text-primary rounded border-gray-300 focus:ring-primary">
                            <label for="removeDuplicates" class="ml-2 text-gray-700">移除重复条目</label>
                        </div>
                        <div class="flex items-center">
                            <input type="checkbox" id="autoGroup" checked class="w-4 h-4 text-primary rounded border-gray-300 focus:ring-primary">
                            <label for="autoGroup" class="ml-2 text-gray-700">自动分组</label>
                        </div>
                        <div class="flex items-center">
                            <input type="checkbox" id="sortChannels" class="w-4 h-4 text-primary rounded border-gray-300 focus:ring-primary">
                            <label for="sortChannels" class="ml-2 text-gray-700">按名称排序</label>
                        </div>
                        <div class="flex items-center">
                            <input type="checkbox" id="cleanNames" class="w-4 h-4 text-primary rounded border-gray-300 focus:ring-primary">
                            <label for="cleanNames" class="ml-2 text-gray-700">清理频道名称</label>
                        </div>
                    </div>
                </div>
                
                <div class="mb-6">
                    <h3 class="font-medium text-gray-700 mb-3">处理结果</h3>
                    <div class="grid grid-cols-2 md:grid-cols-4 gap-4 text-center">
                        <div class="bg-blue-50 p-4 rounded-lg">
                            <p class="text-sm text-gray-600">原始总条目</p>
                            <p id="originalCount" class="text-xl font-bold text-primary">0</p>
                        </div>
                        <div class="bg-green-50 p-4 rounded-lg">
                            <p class="text-sm text-gray-600">去重后条目</p>
                            <p id="uniqueCount" class="text-xl font-bold text-secondary">0</p>
                        </div>
                        <div class="bg-purple-50 p-4 rounded-lg">
                            <p class="text-sm text-gray-600">自动分组数</p>
                            <p id="groupCount" class="text-xl font-bold text-accent">0</p>
                        </div>
                        <div class="bg-yellow-50 p-4 rounded-lg">
                            <p class="text-sm text-gray-600">处理时间</p>
                            <p id="processTime" class="text-xl font-bold text-yellow-600">0ms</p>
                        </div>
                    </div>
                </div>
                
                <div class="flex justify-between">
                    <button id="backToStep1" class="border border-gray-300 hover:bg-gray-100 text-gray-700 font-medium py-2 px-6 rounded-lg transition-all duration-300">
                        <i class="fa fa-arrow-left mr-1"></i>返回
                    </button>
                    <button id="toStep3Btn" class="bg-primary hover:bg-primary/90 text-white font-medium py-2 px-6 rounded-lg transition-all duration-300 transform hover:scale-105">
                        <i class="fa fa-arrow-right mr-1"></i>分组管理
                    </button>
                </div>
            </div>
        </section>

        <!-- 步骤3: 分组管理 -->
        <section id="step3" class="mb-8 hidden">
            <div class="bg-white rounded-xl shadow-lg p-6 md:p-8 transition-all duration-300 hover:shadow-xl">
                <h2 class="text-xl md:text-2xl font-bold mb-6 text-gray-800 flex items-center">
                    <i class="fa fa-list text-primary mr-2"></i>分组与频道管理
                </h2>
                
                <div class="flex flex-col md:flex-row gap-6 mb-6">
                    <!-- 分组列表 -->
                    <div class="md:w-1/4">
                        <div class="flex justify-between items-center mb-3">
                            <h3 class="font-medium text-gray-700">分组列表</h3>
                            <button id="addGroupBtn" class="text-primary hover:text-primary/80 transition-colors">
                                <i class="fa fa-plus-circle"></i> 添加分组
                            </button>
                        </div>
                        <div class="border rounded-lg overflow-hidden">
                            <div class="bg-gray-50 p-2 border-b">
                                <input type="text" id="groupSearch" placeholder="搜索分组..." class="w-full px-3 py-2 text-sm border rounded-lg focus:outline-none focus:ring-2 focus:ring-primary/50">
                            </div>
                            <div id="groupsList" class="max-h-96 overflow-y-auto scrollbar-hide">
                                <!-- 分组会动态添加到这里 -->
                            </div>
                        </div>
                    </div>
                    
                    <!-- 频道列表 -->
                    <div class="md:w-3/4">
                        <div class="flex flex-wrap justify-between items-center mb-3 gap-2">
                            <h3 class="font-medium text-gray-700" id="currentGroupName">所有频道</h3>
                            <div class="flex gap-2">
                                <div class="relative">
                                    <input type="text" id="channelSearch" placeholder="搜索频道..." class="w-full md:w-64 px-3 py-2 text-sm border rounded-lg focus:outline-none focus:ring-2 focus:ring-primary/50">
                                    <i class="fa fa-search absolute right-3 top-1/2 transform -translate-y-1/2 text-gray-400"></i>
                                </div>
                                <button id="ungroupedBtn" class="text-sm border border-gray-300 hover:bg-gray-100 text-gray-700 py-2 px-4 rounded-lg transition-all duration-300">
                                    <i class="fa fa-question-circle mr-1"></i>未分组
                                </button>
                            </div>
                        </div>
                        
                        <div class="border rounded-lg overflow-hidden">
                            <div class="bg-gray-50 p-2 border-b flex flex-wrap gap-2">
                                <button id="moveToGroupBtn" class="text-sm bg-primary/10 hover:bg-primary/20 text-primary py-1 px-3 rounded-lg transition-all duration-300 disabled:opacity-50 disabled:cursor-not-allowed" disabled>
                                    <i class="fa fa-arrows mr-1"></i>移动到分组
                                </button>
                                <button id="renameChannelBtn" class="text-sm bg-blue-50 hover:bg-blue-100 text-blue-600 py-1 px-3 rounded-lg transition-all duration-300 disabled:opacity-50 disabled:cursor-not-allowed" disabled>
                                    <i class="fa fa-pencil mr-1"></i>重命名
                                </button>
                                <button id="removeChannelBtn" class="text-sm bg-red-50 hover:bg-red-100 text-red-600 py-1 px-3 rounded-lg transition-all duration-300 disabled:opacity-50 disabled:cursor-not-allowed" disabled>
                                    <i class="fa fa-trash mr-1"></i>删除
                                </button>
                            </div>
                            <div id="channelsList" class="max-h-96 overflow-y-auto scrollbar-hide">
                                <!-- 频道会动态添加到这里 -->
                            </div>
                        </div>
                    </div>
                </div>
                
                <div class="flex justify-between">
                    <button id="backToStep2" class="border border-gray-300 hover:bg-gray-100 text-gray-700 font-medium py-2 px-6 rounded-lg transition-all duration-300">
                        <i class="fa fa-arrow-left mr-1"></i>返回
                    </button>
                    <button id="toStep4Btn" class="bg-primary hover:bg-primary/90 text-white font-medium py-2 px-6 rounded-lg transition-all duration-300 transform hover:scale-105">
                        <i class="fa fa-arrow-right mr-1"></i>预览与导出
                    </button>
                </div>
            </div>
        </section>

        <!-- 步骤4: 预览与导出 -->
        <section id="step4" class="mb-8 hidden">
            <div class="bg-white rounded-xl shadow-lg p-6 md:p-8 transition-all duration-300 hover:shadow-xl">
                <h2 class="text-xl md:text-2xl font-bold mb-6 text-gray-800 flex items-center">
                    <i class="fa fa-eye text-primary mr-2"></i>预览与导出
                </h2>
                
                <div class="mb-6">
                    <div class="flex justify-between items-center mb-3">
                        <h3 class="font-medium text-gray-700">播放列表预览</h3>
                        <div class="flex gap-2">
                            <select id="previewGroupSelect" class="text-sm border border-gray-300 rounded-lg px-3 py-2 focus:outline-none focus:ring-2 focus:ring-primary/50">
                                <option value="all">所有分组</option>
                            </select>
                        </div>
                    </div>
                    
                    <div class="border rounded-lg overflow-hidden">
                        <div class="bg-gray-50 p-2 border-b grid grid-cols-4 text-sm font-medium text-gray-600">
                            <div>频道名称</div>
                            <div class="hidden md:block">分组</div>
                            <div class="hidden lg:block">URL</div>
                            <div class="text-center">操作</div>
                        </div>
                        <div id="previewList" class="max-h-96 overflow-y-auto scrollbar-hide">
                            <!-- 预览内容会动态添加到这里 -->
                        </div>
                    </div>
                </div>
                
                <div class="mb-6">
                    <h3 class="font-medium text-gray-700 mb-3">导出选项</h3>
                    <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
                        <div class="flex items-center">
                            <input type="checkbox" id="includeGroups" checked class="w-4 h-4 text-primary rounded border-gray-300 focus:ring-primary">
                            <label for="includeGroups" class="ml-2 text-gray-700">导出时包含分组信息</label>
                        </div>
                        <div class="flex items-center">
                            <input type="checkbox" id="formatM3U8" class="w-4 h-4 text-primary rounded border-gray-300 focus:ring-primary">
                            <label for="formatM3U8" class="ml-2 text-gray-700">导出为M3U8格式</label>
                        </div>
                    </div>
                    
                    <div class="mt-4">
                        <label for="outputFileName" class="block text-sm font-medium text-gray-700 mb-1">文件名</label>
                        <input type="text" id="outputFileName" value="playlist" class="w-full px-3 py-2 border rounded-lg focus:outline-none focus:ring-2 focus:ring-primary/50">
                    </div>
                </div>
                
                <div class="flex justify-between">
                    <button id="backToStep3" class="border border-gray-300 hover:bg-gray-100 text-gray-700 font-medium py-2 px-6 rounded-lg transition-all duration-300">
                        <i class="fa fa-arrow-left mr-1"></i>返回
                    </button>
                    <div class="flex gap-3">
                        <button id="saveBtn" class="bg-secondary hover:bg-secondary/90 text-white font-medium py-2 px-6 rounded-lg transition-all duration-300 transform hover:scale-105">
                            <i class="fa fa-download mr-1"></i>下载播放列表
                        </button>
                        <button id="newProcessBtn" class="border border-primary text-primary hover:bg-primary/10 font-medium py-2 px-6 rounded-lg transition-all duration-300">
                            <i class="fa fa-refresh mr-1"></i>新的处理
                        </button>
                    </div>
                </div>
            </div>
        </section>
    </main>

    <!-- 帮助模态框 -->
    <div id="helpModal" class="fixed inset-0 bg-black/50 z-50 flex items-center justify-center hidden">
        <div class="bg-white rounded-xl shadow-2xl max-w-2xl w-full max-h-[90vh] overflow-y-auto m-4">
            <div class="p-6 border-b">
                <div class="flex justify-between items-center">
                    <h3 class="text-xl font-bold text-gray-800">使用帮助</h3>
                    <button id="closeHelpBtn" class="text-gray-500 hover:text-gray-700">
                        <i class="fa fa-times text-xl"></i>
                    </button>
                </div>
            </div>
            <div class="p-6 space-y-4">
                <div>
                    <h4 class="font-bold text-gray-800 mb-2">1. 上传文件</h4>
                    <p class="text-gray-600">点击"选择文件"按钮或直接拖放M3U/M3U8文件到上传区域，可以同时上传多个文件。</p>
                </div>
                <div>
                    <h4 class="font-bold text-gray-800 mb-2">2. 处理列表</h4>
                    <p class="text-gray-600">选择需要的处理选项，系统会自动合并文件、去除重复项并进行初步分组。</p>
                </div>
                <div>
                    <h4 class="font-bold text-gray-800 mb-2">3. 分组管理</h4>
                    <p class="text-gray-600">可以查看自动分组结果，也可以手动创建新分组、移动频道到不同分组、重命名或删除频道。</p>
                </div>
                <div>
                    <h4 class="font-bold text-gray-800 mb-2">4. 预览与导出</h4>
                    <p class="text-gray-600">预览最终的播放列表，选择导出选项并下载处理后的M3U文件。</p>
                </div>
            </div>
        </div>
    </div>

    <!-- 添加分组模态框 -->
    <div id="addGroupModal" class="fixed inset-0 bg-black/50 z-50 flex items-center justify-center hidden">
        <div class="bg-white rounded-xl shadow-2xl max-w-md w-full m-4">
            <div class="p-6 border-b">
                <div class="flex justify-between items-center">
                    <h3 class="text-xl font-bold text-gray-800">添加新分组</h3>
                    <button id="closeAddGroupBtn" class="text-gray-500 hover:text-gray-700">
                        <i class="fa fa-times text-xl"></i>
                    </button>
                </div>
            </div>
            <div class="p-6">
                <div class="mb-4">
                    <label for="newGroupName" class="block text-sm font-medium text-gray-700 mb-1">分组名称</label>
                    <input type="text" id="newGroupName" class="w-full px-3 py-2 border rounded-lg focus:outline-none focus:ring-2 focus:ring-primary/50" placeholder="例如：电影、体育">
                </div>
                <div class="flex justify-end">
                    <button id="confirmAddGroupBtn" class="bg-primary hover:bg-primary/90 text-white font-medium py-2 px-6 rounded-lg transition-all duration-300">
                        确认添加
                    </button>
                </div>
            </div>
        </div>
    </div>

    <!-- 移动到分组模态框 -->
    <div id="moveToGroupModal" class="fixed inset-0 bg-black/50 z-50 flex items-center justify-center hidden">
        <div class="bg-white rounded-xl shadow-2xl max-w-md w-full m-4">
            <div class="p-6 border-b">
                <div class="flex justify-between items-center">
                    <h3 class="text-xl font-bold text-gray-800">移动到分组</h3>
                    <button id="closeMoveToGroupBtn" class="text-gray-500 hover:text-gray-700">
                        <i class="fa fa-times text-xl"></i>
                    </button>
                </div>
            </div>
            <div class="p-6">
                <div class="mb-4">
                    <label for="targetGroupSelect" class="block text-sm font-medium text-gray-700 mb-1">选择目标分组</label>
                    <select id="targetGroupSelect" class="w-full px-3 py-2 border rounded-lg focus:outline-none focus:ring-2 focus:ring-primary/50">
                        <option value="">-- 选择分组 --</option>
                        <!-- 分组选项会动态添加 -->
                    </select>
                </div>
                <div class="flex justify-end">
                    <button id="confirmMoveBtn" class="bg-primary hover:bg-primary/90 text-white font-medium py-2 px-6 rounded-lg transition-all duration-300">
                        确认移动
                    </button>
                </div>
            </div>
        </div>
    </div>

    <!-- 重命名频道模态框 -->
    <div id="renameChannelModal" class="fixed inset-0 bg-black/50 z-50 flex items-center justify-center hidden">
        <div class="bg-white rounded-xl shadow-2xl max-w-md w-full m-4">
            <div class="p-6 border-b">
                <div class="flex justify-between items-center">
                    <h3 class="text-xl font-bold text-gray-800">重命名频道</h3>
                    <button id="closeRenameChannelBtn" class="text-gray-500 hover:text-gray-700">
                        <i class="fa fa-times text-xl"></i>
                    </button>
                </div>
            </div>
            <div class="p-6">
                <div class="mb-4">
                    <label for="newChannelName" class="block text-sm font-medium text-gray-700 mb-1">新频道名称</label>
                    <input type="text" id="newChannelName" class="w-full px-3 py-2 border rounded-lg focus:outline-none focus:ring-2 focus:ring-primary/50">
                </div>
                <div class="flex justify-end">
                    <button id="confirmRenameBtn" class="bg-primary hover:bg-primary/90 text-white font-medium py-2 px-6 rounded-lg transition-all duration-300">
                        确认重命名
                    </button>
                </div>
            </div>
        </div>
    </div>

    <!-- 确认删除模态框 -->
    <div id="confirmDeleteModal" class="fixed inset-0 bg-black/50 z-50 flex items-center justify-center hidden">
        <div class="bg-white rounded-xl shadow-2xl max-w-md w-full m-4">
            <div class="p-6 border-b">
                <div class="flex justify-between items-center">
                    <h3 class="text-xl font-bold text-gray-800">确认删除</h3>
                    <button id="closeConfirmDeleteBtn" class="text-gray-500 hover:text-gray-700">
                        <i class="fa fa-times text-xl"></i>
                    </button>
                </div>
            </div>
            <div class="p-6">
                <p class="text-gray-600 mb-6" id="deleteConfirmMessage">您确定要删除选中的项目吗？此操作无法撤销。</p>
                <div class="flex justify-end gap-3">
                    <button id="cancelDeleteBtn" class="border border-gray-300 hover:bg-gray-100 text-gray-700 font-medium py-2 px-6 rounded-lg transition-all duration-300">
                        取消
                    </button>
                    <button id="confirmDeleteBtn" class="bg-red-500 hover:bg-red-600 text-white font-medium py-2 px-6 rounded-lg transition-all duration-300">
                        确认删除
                    </button>
                </div>
            </div>
        </div>
    </div>

    <!-- 页脚 -->
    <footer class="bg-white border-t border-gray-200 py-4">
        <div class="container mx-auto px-4 text-center text-gray-500 text-sm">
            <p>M3U播放列表管理器 &copy; 2023 - 一个简单高效的M3U处理工具</p>
        </div>
    </footer>

    <script>
        // 全局数据存储
        const appData = {
            files: [],
            channels: [],
            groups: [],
            selectedChannelIds: new Set(),
            currentGroupId: null
        };

        // DOM元素
        const elements = {
            // 步骤元素
            step1: document.getElementById('step1'),
            step2: document.getElementById('step2'),
            step3: document.getElementById('step3'),
            step4: document.getElementById('step4'),
            
            // 步骤指示器
            step1Icon: document.getElementById('step1Icon'),
            step2Icon: document.getElementById('step2Icon'),
            step3Icon: document.getElementById('step3Icon'),
            step4Icon: document.getElementById('step4Icon'),
            progress1: document.getElementById('progress1'),
            progress2: document.getElementById('progress2'),
            progress3: document.getElementById('progress3'),
            
            // 步骤1元素
            dropArea: document.getElementById('dropArea'),
            fileInput: document.getElementById('fileInput'),
            fileList: document.getElementById('fileList'),
            selectedFiles: document.getElementById('selectedFiles'),
            processBtn: document.getElementById('processBtn'),
            
            // 步骤2元素
            removeDuplicates: document.getElementById('removeDuplicates'),
            autoGroup: document.getElementById('autoGroup'),
            sortChannels: document.getElementById('sortChannels'),
            cleanNames: document.getElementById('cleanNames'),
            originalCount: document.getElementById('originalCount'),
            uniqueCount: document.getElementById('uniqueCount'),
            groupCount: document.getElementById('groupCount'),
            processTime: document.getElementById('processTime'),
            backToStep1: document.getElementById('backToStep1'),
            toStep3Btn: document.getElementById('toStep3Btn'),
            
            // 步骤3元素
            groupsList: document.getElementById('groupsList'),
            currentGroupName: document.getElementById('currentGroupName'),
            channelsList: document.getElementById('channelsList'),
            addGroupBtn: document.getElementById('addGroupBtn'),
            groupSearch: document.getElementById('groupSearch'),
            channelSearch: document.getElementById('channelSearch'),
            ungroupedBtn: document.getElementById('ungroupedBtn'),
            moveToGroupBtn: document.getElementById('moveToGroupBtn'),
            renameChannelBtn: document.getElementById('renameChannelBtn'),
            removeChannelBtn: document.getElementById('removeChannelBtn'),
            backToStep2: document.getElementById('backToStep2'),
            toStep4Btn: document.getElementById('toStep4Btn'),
            
            // 步骤4元素
            previewGroupSelect: document.getElementById('previewGroupSelect'),
            previewList: document.getElementById('previewList'),
            includeGroups: document.getElementById('includeGroups'),
            formatM3U8: document.getElementById('formatM3U8'),
            outputFileName: document.getElementById('outputFileName'),
            saveBtn: document.getElementById('saveBtn'),
            newProcessBtn: document.getElementById('newProcessBtn'),
            backToStep3: document.getElementById('backToStep3'),
            
            // 模态框
            helpModal: document.getElementById('helpModal'),
            helpBtn: document.getElementById('helpBtn'),
            closeHelpBtn: document.getElementById('closeHelpBtn'),
            addGroupModal: document.getElementById('addGroupModal'),
            closeAddGroupBtn: document.getElementById('closeAddGroupBtn'),
            newGroupName: document.getElementById('newGroupName'),
            confirmAddGroupBtn: document.getElementById('confirmAddGroupBtn'),
            moveToGroupModal: document.getElementById('moveToGroupModal'),
            closeMoveToGroupBtn: document.getElementById('closeMoveToGroupBtn'),
            targetGroupSelect: document.getElementById('targetGroupSelect'),
            confirmMoveBtn: document.getElementById('confirmMoveBtn'),
            renameChannelModal: document.getElementById('renameChannelModal'),
            closeRenameChannelBtn: document.getElementById('closeRenameChannelBtn'),
            newChannelName: document.getElementById('newChannelName'),
            confirmRenameBtn: document.getElementById('confirmRenameBtn'),
            confirmDeleteModal: document.getElementById('confirmDeleteModal'),
            closeConfirmDeleteBtn: document.getElementById('closeConfirmDeleteBtn'),
            cancelDeleteBtn: document.getElementById('cancelDeleteBtn'),
            confirmDeleteBtn: document.getElementById('confirmDeleteBtn'),
            deleteConfirmMessage: document.getElementById('deleteConfirmMessage'),
            
            // 主题切换
            themeToggle: document.getElementById('themeToggle')
        };

        // 初始化应用
        function initApp() {
            setupEventListeners();
        }

        // 设置事件监听器
        function setupEventListeners() {
            // 步骤1事件
            elements.dropArea.addEventListener('dragover', handleDragOver);
            elements.dropArea.addEventListener('drop', handleDrop);
            elements.fileInput.addEventListener('change', handleFileSelect);
            elements.processBtn.addEventListener('click', processFiles);
            
            // 步骤导航事件
            elements.backToStep1.addEventListener('click', () => goToStep(1));
            elements.toStep3Btn.addEventListener('click', () => goToStep(3));
            elements.backToStep2.addEventListener('click', () => goToStep(2));
            elements.toStep4Btn.addEventListener('click', () => {
                goToStep(4);
                updatePreview();
            });
            elements.backToStep3.addEventListener('click', () => goToStep(3));
            elements.newProcessBtn.addEventListener('click', resetApp);
            
            // 步骤3事件
            elements.addGroupBtn.addEventListener('click', openAddGroupModal);
            elements.closeAddGroupBtn.addEventListener('click', closeAddGroupModal);
            elements.confirmAddGroupBtn.addEventListener('click', addNewGroup);
            elements.groupSearch.addEventListener('input', filterGroups);
            elements.channelSearch.addEventListener('input', filterChannels);
            elements.ungroupedBtn.addEventListener('click', showUngroupedChannels);
            elements.moveToGroupBtn.addEventListener('click', openMoveToGroupModal);
            elements.closeMoveToGroupBtn.addEventListener('click', closeMoveToGroupModal);
            elements.confirmMoveBtn.addEventListener('click', moveChannelsToGroup);
            elements.renameChannelBtn.addEventListener('click', openRenameChannelModal);
            elements.closeRenameChannelBtn.addEventListener('click', closeRenameChannelModal);
            elements.confirmRenameBtn.addEventListener('click', renameSelectedChannel);
            elements.removeChannelBtn.addEventListener('click', openConfirmDeleteModal);
            elements.closeConfirmDeleteBtn.addEventListener('click', closeConfirmDeleteModal);
            elements.cancelDeleteBtn.addEventListener('click', closeConfirmDeleteModal);
            elements.confirmDeleteBtn.addEventListener('click', deleteSelectedChannels);
            
            // 步骤4事件
            elements.previewGroupSelect.addEventListener('change', updatePreview);
            elements.saveBtn.addEventListener('click', exportPlaylist);
            
            // 帮助模态框
            elements.helpBtn.addEventListener('click', openHelpModal);
            elements.closeHelpBtn.addEventListener('click', closeHelpModal);
            
            // 点击模态框外部关闭
            elements.helpModal.addEventListener('click', (e) => {
                if (e.target === elements.helpModal) closeHelpModal();
            });
            elements.addGroupModal.addEventListener('click', (e) => {
                if (e.target === elements.addGroupModal) closeAddGroupModal();
            });
            elements.moveToGroupModal.addEventListener('click', (e) => {
                if (e.target === elements.moveToGroupModal) closeMoveToGroupModal();
            });
            elements.renameChannelModal.addEventListener('click', (e) => {
                if (e.target === elements.renameChannelModal) closeRenameChannelModal();
            });
            elements.confirmDeleteModal.addEventListener('click', (e) => {
                if (e.target === elements.confirmDeleteModal) closeConfirmDeleteModal();
            });
            
            // 主题切换
            elements.themeToggle.addEventListener('click', toggleTheme);
        }

        // 拖拽事件处理
        function handleDragOver(e) {
            e.preventDefault();
            elements.dropArea.classList.add('border-primary', 'bg-blue-50');
        }

        function handleDrop(e) {
            e.preventDefault();
            elements.dropArea.classList.remove('border-primary', 'bg-blue-50');
            
            if (e.dataTransfer.files.length) {
                const files = Array.from(e.dataTransfer.files)
                    .filter(file => file.name.toLowerCase().endsWith('.m3u') || file.name.toLowerCase().endsWith('.m3u8'));
                
                if (files.length) {
                    addFiles(files);
                }
            }
        }

        // 文件选择处理
        function handleFileSelect(e) {
            if (e.target.files.length) {
                const files = Array.from(e.target.files);
                addFiles(files);
                // 重置输入以允许重新选择相同文件
                elements.fileInput.value = '';
            }
        }

        // 添加文件到列表
        function addFiles(files) {
            // 过滤重复文件
            const newFiles = files.filter(file => 
                !appData.files.some(f => f.name === file.name && f.size === file.size)
            );
            
            if (newFiles.length === 0) return;
            
            appData.files = [...appData.files, ...newFiles];
            renderFileList();
            elements.processBtn.disabled = appData.files.length === 0;
            elements.fileList.classList.remove('hidden');
        }

        // 渲染文件列表
        function renderFileList() {
            elements.selectedFiles.innerHTML = '';
            
            appData.files.forEach((file, index) => {
                const li = document.createElement('li');
                li.className = 'flex justify-between items-center p-2 hover:bg-gray-50 rounded';
                li.innerHTML = `
                    <div class="flex items-center">
                        <i class="fa fa-file-text-o text-gray-500 mr-2"></i>
                        <span class="truncate max-w-[200px] md:max-w-[300px]">${file.name}</span>
                    </div>
                    <button class="text-red-500 hover:text-red-700 transition-colors" data-index="${index}">
                        <i class="fa fa-times"></i>
                    </button>
                `;
                elements.selectedFiles.appendChild(li);
            });
            
            // 添加删除文件事件
            document.querySelectorAll('#selectedFiles button').forEach(btn => {
                btn.addEventListener('click', (e) => {
                    const index = parseInt(e.currentTarget.dataset.index);
                    appData.files.splice(index, 1);
                    renderFileList();
                    elements.processBtn.disabled = appData.files.length === 0;
                    if (appData.files.length === 0) {
                        elements.fileList.classList.add('hidden');
                    }
                });
            });
        }

        // 处理文件
        function processFiles() {
            const startTime = performance.now();
            appData.channels = [];
            appData.groups = [];
            
            // 读取并解析所有文件
            const promises = appData.files.map(file => {
                return new Promise((resolve, reject) => {
                    const reader = new FileReader();
                    reader.onload = (e) => {
                        const content = e.target.result;
                        const channels = parseM3U(content, file.name);
                        appData.channels = [...appData.channels, ...channels];
                        resolve();
                    };
                    reader.onerror = reject;
                    reader.readAsText(file);
                });
            });
            
            Promise.all(promises).then(() => {
                // 处理频道
                const originalCount = appData.channels.length;
                
                // 去重
                if (elements.removeDuplicates.checked) {
                    const uniqueUrls = new Set();
                    appData.channels = appData.channels.filter(channel => {
                        if (uniqueUrls.has(channel.url)) {
                            return false;
                        }
                        uniqueUrls.add(channel.url);
                        return true;
                    });
                }
                
                // 清理名称
                if (elements.cleanNames.checked) {
                    appData.channels.forEach(channel => {
                        channel.name = cleanChannelName(channel.name);
                    });
                }
                
                // 自动分组
                if (elements.autoGroup.checked) {
                    createAutoGroups();
                }
                
                // 排序
                if (elements.sortChannels.checked) {
                    appData.channels.sort((a, b) => a.name.localeCompare(b.name));
                }
                
                // 更新统计信息
                elements.originalCount.textContent = originalCount;
                elements.uniqueCount.textContent = appData.channels.length;
                elements.groupCount.textContent = appData.groups.length;
                
                const endTime = performance.now();
                elements.processTime.textContent = `${Math.round(endTime - startTime)}ms`;
                
                // 进入步骤2
                goToStep(2);
            }).catch(error => {
                console.error('Error processing files:', error);
                alert('处理文件时出错: ' + error.message);
            });
        }

        // 解析M3U内容
        function parseM3U(content, fileName) {
            const lines = content.split('\n');
            const channels = [];
            let currentInfo = null;
            
            lines.forEach(line => {
                line = line.trim();
                if (line.startsWith('#EXTINF:')) {
                    // 解析EXTINF行
                    const infoMatch = line.match(/#EXTINF:(-?\d+)(.*),(.*)/);
                    if (infoMatch && infoMatch.length >= 4) {
                        const duration = parseInt(infoMatch[1]);
                        const params = infoMatch[2];
                        const name = infoMatch[3].trim();
                        currentInfo = { duration, params, name };
                    }
                } else if (line && !line.startsWith('#') && currentInfo) {
                    // 这是一个URL行
                    channels.push({
                        id: generateId(),
                        name: currentInfo.name,
                        url: line,
                        duration: currentInfo.duration,
                        params: currentInfo.params,
                        source: fileName,
                        groupId: null
                    });
                    currentInfo = null;
                }
            });
            
            return channels;
        }

        // 清理频道名称
        function cleanChannelName(name) {
            // 移除常见的前缀和后缀
            const patterns = [
                /^\d+\./, // 数字前缀如 "1."
                /\[.*?\]/g, // 方括号内容如 [HD]
                /\(.*?\)/g, // 圆括号内容如 (高清)
                /【.*?】/g, // 中文括号内容
                /<.*?>/g, // HTML标签
                /\s+/g // 多余空格
            ];
            
            let cleaned = name;
            patterns.forEach(pattern => {
                cleaned = cleaned.replace(pattern, ' ');
            });
            
            // 去除首尾空格并标准化空格
            return cleaned.trim().replace(/\s+/g, ' ');
        }

        // 创建自动分组
        function createAutoGroups() {
            const groupNames = new Set();
            const genreKeywords = [
                '电影', '电视剧', '综艺', '体育', '新闻', '财经', '音乐', 
                '少儿', '科教', '纪实', '卡通', '动漫', '游戏', '戏曲',
                'HD', '高清', '4K', '卫视', '央视', '地方', '国际'
            ];
            
            // 从频道名称中提取可能的分组名称
            appData.channels.forEach(channel => {
                let foundGroup = null;
                
                // 检查关键词
                for (const keyword of genreKeywords) {
                    if (channel.name.includes(keyword)) {
                        foundGroup = keyword;
                        break;
                    }
                }
                
                // 如果没有找到关键词，尝试使用来源文件名作为分组
                if (!foundGroup && channel.source) {
                    const sourceName = channel.source.replace(/\.(m3u|m3u8)$/i, '');
                    foundGroup = sourceName;
                }
                
                if (foundGroup) {
                    groupNames.add(foundGroup);
                    
                    // 查找或创建分组
                    let group = appData.groups.find(g => g.name === foundGroup);
                    if (!group) {
                        group = {
                            id: generateId(),
                            name: foundGroup
                        };
                        appData.groups.push(group);
                    }
                    
                    channel.groupId = group.id;
                }
            });
        }

        // 生成唯一ID
        function generateId() {
            return Date.now().toString(36) + Math.random().toString(36).substr(2, 5);
        }

        // 导航到指定步骤
        function goToStep(step) {
            // 隐藏所有步骤
            elements.step1.classList.add('hidden');
            elements.step2.classList.add('hidden');
            elements.step3.classList.add('hidden');
            elements.step4.classList.add('hidden');
            
            // 重置所有步骤图标
            [elements.step1Icon, elements.step2Icon, elements.step3Icon, elements.step4Icon].forEach(icon => {
                icon.className = 'w-10 h-10 rounded-full bg-gray-200 text-gray-600 flex items-center justify-center mb-2';
            });
            
            // 重置进度条
            elements.progress1.style.width = '0%';
            elements.progress2.style.width = '0%';
            elements.progress3.style.width = '0%';
            
            // 显示当前步骤
            switch(step) {
                case 1:
                    elements.step1.classList.remove('hidden');
                    elements.step1Icon.className = 'w-10 h-10 rounded-full bg-primary text-white flex items-center justify-center mb-2';
                    break;
                case 2:
                    elements.step2.classList.remove('hidden');
                    elements.step1Icon.className = 'w-10 h-10 rounded-full bg-primary text-white flex items-center justify-center mb-2';
                    elements.step2Icon.className = 'w-10 h-10 rounded-full bg-primary text-white flex items-center justify-center mb-2';
                    elements.progress1.style.width = '100%';
                    renderGroupsList();
                    break;
                case 3:
                    elements.step3.classList.remove('hidden');
                    elements.step1Icon.className = 'w-10 h-10 rounded-full bg-primary text-white flex items-center justify-center mb-2';
                    elements.step2Icon.className = 'w-10 h-10 rounded-full bg-primary text-white flex items-center justify-center mb-2';
                    elements.step3Icon.className = 'w-10 h-10 rounded-full bg-primary text-white flex items-center justify-center mb-2';
                    elements.progress1.style.width = '100%';
                    elements.progress2.style.width = '100%';
                    renderGroupsList();
                    showAllChannels();
                    break;
                case 4:
                    elements.step4.classList.remove('hidden');
                    elements.step1Icon.className = 'w-10 h-10 rounded-full bg-primary text-white flex items-center justify-center mb-2';
                    elements.step2Icon.className = 'w-10 h-10 rounded-full bg-primary text-white flex items-center justify-center mb-2';
                    elements.step3Icon.className = 'w-10 h-10 rounded-full bg-primary text-white flex items-center justify-center mb-2';
                    elements.step4Icon.className = 'w-10 h-10 rounded-full bg-primary text-white flex items-center justify-center mb-2';
                    elements.progress1.style.width = '100%';
                    elements.progress2.style.width = '100%';
                    elements.progress3.style.width = '100%';
                    updatePreviewGroupSelect();
                    break;
            }
        }

        // 渲染分组列表
        function renderGroupsList() {
            elements.groupsList.innerHTML = '';
            
            // 添加"所有频道"选项
            const allItem = document.createElement('div');
            allItem.className = `p-3 hover:bg-gray-100 cursor-pointer ${appData.currentGroupId === null ? 'bg-primary/10 text-primary' : ''}`;
            allItem.innerHTML = `<i class="fa fa-list-ul mr-2"></i>所有频道`;
            allItem.addEventListener('click', () => {
                appData.currentGroupId = null;
                showAllChannels();
                renderGroupsList();
            });
            elements.groupsList.appendChild(allItem);
            
            // 添加未分组选项
            const ungroupedCount = appData.channels.filter(c => !c.groupId).length;
            if (ungroupedCount > 0) {
                const ungroupedItem = document.createElement('div');
                ungroupedItem.className = `p-3 hover:bg-gray-100 cursor-pointer ${appData.currentGroupId === 'ungrouped' ? 'bg-primary/10 text-primary' : ''}`;
                ungroupedItem.innerHTML = `<i class="fa fa-question-circle mr-2"></i>未分组 <span class="text-xs bg-gray-200 rounded-full px-1.5">${ungroupedCount}</span>`;
                ungroupedItem.addEventListener('click', () => {
                    appData.currentGroupId = 'ungrouped';
                    showUngroupedChannels();
                    renderGroupsList();
                });
                elements.groupsList.appendChild(ungroupedItem);
            }
            
            // 添加分组
            appData.groups.forEach(group => {
                const groupChannelsCount = appData.channels.filter(c => c.groupId === group.id).length;
                if (groupChannelsCount === 0) return;
                
                const groupItem = document.createElement('div');
                groupItem.className = `p-3 hover:bg-gray-100 cursor-pointer ${appData.currentGroupId === group.id ? 'bg-primary/10 text-primary' : ''}`;
                groupItem.innerHTML = `
                    <div class="flex justify-between items-center">
                        <span><i class="fa fa-folder mr-2"></i>${group.name}</span>
                        <span class="text-xs bg-gray-200 rounded-full px-1.5">${groupChannelsCount}</span>
                    </div>
                `;
                groupItem.addEventListener('click', () => {
                    appData.currentGroupId = group.id;
                    showGroupChannels(group.id);
                    renderGroupsList();
                });
                elements.groupsList.appendChild(groupItem);
            });
            
            // 更新移动到分组的下拉列表
            updateTargetGroupSelect();
        }

        // 更新目标分组选择下拉框
        function updateTargetGroupSelect() {
            elements.targetGroupSelect.innerHTML = '<option value="">-- 选择分组 --</option>';
            
            appData.groups.forEach(group => {
                const option = document.createElement('option');
                option.value = group.id;
                option.textContent = group.name;
                elements.targetGroupSelect.appendChild(option);
            });
        }

        // 显示所有频道
        function showAllChannels() {
            appData.selectedChannelIds.clear();
            elements.currentGroupName.textContent = '所有频道';
            renderChannelsList(appData.channels);
            updateChannelActionButtons();
        }

        // 显示特定分组的频道
        function showGroupChannels(groupId) {
            appData.selectedChannelIds.clear();
            const group = appData.groups.find(g => g.id === groupId);
            elements.currentGroupName.textContent = group ? group.name : '未知分组';
            const groupChannels = appData.channels.filter(channel => channel.groupId === groupId);
            renderChannelsList(groupChannels);
            updateChannelActionButtons();
        }

        // 显示未分组的频道
        function showUngroupedChannels() {
            appData.selectedChannelIds.clear();
            elements.currentGroupName.textContent = '未分组频道';
            const ungroupedChannels = appData.channels.filter(channel => !channel.groupId);
            renderChannelsList(ungroupedChannels);
            updateChannelActionButtons();
        }

        // 过滤分组
        function filterGroups() {
            const searchTerm = elements.groupSearch.value.toLowerCase();
            const items = elements.groupsList.querySelectorAll('div');
            
            items.forEach(item => {
                const text = item.textContent.toLowerCase();
                if (text.includes(searchTerm)) {
                    item.style.display = '';
                } else {
                    item.style.display = 'none';
                }
            });
        }

        // 过滤频道
        function filterChannels() {
            const searchTerm = elements.channelSearch.value.toLowerCase();
            let filteredChannels;
            
            if (appData.currentGroupId === null) {
                filteredChannels = appData.channels;
            } else if (appData.currentGroupId === 'ungrouped') {
                filteredChannels = appData.channels.filter(channel => !channel.groupId);
            } else {
                filteredChannels = appData.channels.filter(channel => channel.groupId === appData.currentGroupId);
            }
            
            filteredChannels = filteredChannels.filter(channel => 
                channel.name.toLowerCase().includes(searchTerm) || 
                channel.url.toLowerCase().includes(searchTerm)
            );
            
            renderChannelsList(filteredChannels);
        }

        // 渲染频道列表
        function renderChannelsList(channels) {
            elements.channelsList.innerHTML = '';
            
            if (channels.length === 0) {
                elements.channelsList.innerHTML = `
                    <div class="p-6 text-center text-gray-500">
                        <i class="fa fa-info-circle text-2xl mb-2"></i>
                        <p>没有找到频道</p>
                    </div>
                `;
                return;
            }
            
            channels.forEach(channel => {
                const group = appData.groups.find(g => g.id === channel.groupId);
                const groupName = group ? group.name : '未分组';
                
                const channelItem = document.createElement('div');
                channelItem.className = `p-3 border-b last:border-0 hover:bg-gray-50 ${appData.selectedChannelIds.has(channel.id) ? 'bg-primary/5' : ''}`;
                channelItem.innerHTML = `
                    <div class="flex items-start">
                        <div class="mr-3 mt-0.5">
                            <input type="checkbox" class="channel-checkbox" data-id="${channel.id}" ${appData.selectedChannelIds.has(channel.id) ? 'checked' : ''}>
                        </div>
                        <div class="flex-1 min-w-0">
                            <div class="flex flex-wrap justify-between">
                                <div class="font-medium text-gray-800 truncate">${channel.name}</div>
                                <div class="text-xs text-gray-500 mt-0.5 ml-2">${groupName}</div>
                            </div>
                            <div class="text-xs text-gray-600 mt-1 truncate">${channel.url}</div>
                        </div>
                    </div>
                `;
                elements.channelsList.appendChild(channelItem);
            });
            
            // 添加复选框事件
            document.querySelectorAll('.channel-checkbox').forEach(checkbox => {
                checkbox.addEventListener('change', (e) => {
                    const channelId = e.target.dataset.id;
                    if (e.target.checked) {
                        appData.selectedChannelIds.add(channelId);
                    } else {
                        appData.selectedChannelIds.delete(channelId);
                    }
                    updateChannelActionButtons();
                });
            });
            
            // 添加点击行选中复选框的功能
            document.querySelectorAll('#channelsList > div').forEach(item => {
                item.addEventListener('click', (e) => {
                    if (e.target.type !== 'checkbox' && !e.target.closest('.channel-checkbox')) {
                        const checkbox = item.querySelector('.channel-checkbox');
                        checkbox.checked = !checkbox.checked;
                        checkbox.dispatchEvent(new Event('change'));
                    }
                });
            });
        }

        // 更新频道操作按钮状态
        function updateChannelActionButtons() {
            const hasSelection = appData.selectedChannelIds.size > 0;
            elements.moveToGroupBtn.disabled = !hasSelection;
            elements.removeChannelBtn.disabled = !hasSelection;
            
            // 如果只选中一个频道，启用重命名按钮
            elements.renameChannelBtn.disabled = appData.selectedChannelIds.size !== 1;
        }

        // 打开添加分组模态框
        function openAddGroupModal() {
            elements.newGroupName.value = '';
            elements.addGroupModal.classList.remove('hidden');
            setTimeout(() => {
                elements.newGroupName.focus();
            }, 100);
        }

        // 关闭添加分组模态框
        function closeAddGroupModal() {
            elements.addGroupModal.classList.add('hidden');
        }

        // 添加新分组
        function addNewGroup() {
            const groupName = elements.newGroupName.value.trim();
            if (!groupName) {
                alert('请输入分组名称');
                return;
            }
            
            // 检查是否已存在同名分组
            if (appData.groups.some(g => g.name === groupName)) {
                alert('已存在同名分组');
                return;
            }
            
            // 创建新分组
            const newGroup = {
                id: generateId(),
                name: groupName
            };
            
            appData.groups.push(newGroup);
            renderGroupsList();
            closeAddGroupModal();
        }

        // 打开移动到分组模态框
        function openMoveToGroupModal() {
            updateTargetGroupSelect();
            elements.moveToGroupModal.classList.remove('hidden');
        }

        // 关闭移动到分组模态框
        function closeMoveToGroupModal() {
            elements.moveToGroupModal.classList.add('hidden');
        }

        // 移动频道到指定分组
        function moveChannelsToGroup() {
            const targetGroupId = elements.targetGroupSelect.value;
            if (!targetGroupId) {
                alert('请选择目标分组');
                return;
            }
            
            // 更新频道的分组ID
            appData.channels.forEach(channel => {
                if (appData.selectedChannelIds.has(channel.id)) {
                    channel.groupId = targetGroupId;
                }
            });
            
            // 刷新当前视图
            if (appData.currentGroupId === null) {
                showAllChannels();
            } else if (appData.currentGroupId === 'ungrouped') {
                showUngroupedChannels();
            } else {
                showGroupChannels(appData.currentGroupId);
            }
            
            renderGroupsList();
            closeMoveToGroupModal();
        }

        // 打开重命名频道模态框
        function openRenameChannelModal() {
            if (appData.selectedChannelIds.size !== 1) return;
            
            const channelId = Array.from(appData.selectedChannelIds)[0];
            const channel = appData.channels.find(c => c.id === channelId);
            
            if (channel) {
                elements.newChannelName.value = channel.name;
                elements.renameChannelModal.classList.remove('hidden');
                setTimeout(() => {
                    elements.newChannelName.focus();
                }, 100);
            }
        }

        // 关闭重命名频道模态框
        function closeRenameChannelModal() {
            elements.renameChannelModal.classList.add('hidden');
        }

        // 重命名选中的频道
        function renameSelectedChannel() {
            const newName = elements.newChannelName.value.trim();
            if (!newName) {
                alert('请输入频道名称');
                return;
            }
            
            if (appData.selectedChannelIds.size !== 1) return;
            
            const channelId = Array.from(appData.selectedChannelIds)[0];
            const channel = appData.channels.find(c => c.id === channelId);
            
            if (channel) {
                channel.name = newName;
                
                // 刷新当前视图
                if (appData.currentGroupId === null) {
                    showAllChannels();
                } else if (appData.currentGroupId === 'ungrouped') {
                    showUngroupedChannels();
                } else {
                    showGroupChannels(appData.currentGroupId);
                }
                
                closeRenameChannelModal();
            }
        }

        // 打开确认删除模态框
        function openConfirmDeleteModal() {
            const count = appData.selectedChannelIds.size;
            elements.deleteConfirmMessage.textContent = `您确定要删除选中的 ${count} 个频道吗？此操作无法撤销。`;
            elements.confirmDeleteModal.classList.remove('hidden');
        }

        // 关闭确认删除模态框
        function closeConfirmDeleteModal() {
            elements.confirmDeleteModal.classList.add('hidden');
        }

        // 删除选中的频道
        function deleteSelectedChannels() {
            // 过滤掉选中的频道
            appData.channels = appData.channels.filter(channel => 
                !appData.selectedChannelIds.has(channel.id)
            );
            
            // 清除选择
            appData.selectedChannelIds.clear();
            
            // 刷新当前视图
            if (appData.currentGroupId === null) {
                showAllChannels();
            } else if (appData.currentGroupId === 'ungrouped') {
                showUngroupedChannels();
            } else {
                showGroupChannels(appData.currentGroupId);
            }
            
            renderGroupsList();
            closeConfirmDeleteModal();
        }

        // 更新预览分组选择下拉框
        function updatePreviewGroupSelect() {
            elements.previewGroupSelect.innerHTML = '<option value="all">所有分组</option>';
            
            appData.groups.forEach(group => {
                const groupChannelsCount = appData.channels.filter(c => c.groupId === group.id).length;
                if (groupChannelsCount > 0) {
                    const option = document.createElement('option');
                    option.value = group.id;
                    option.textContent = `${group.name} (${groupChannelsCount})`;
                    elements.previewGroupSelect.appendChild(option);
                }
            });
            
            // 添加未分组选项
            const ungroupedCount = appData.channels.filter(c => !c.groupId).length;
            if (ungroupedCount > 0) {
                const option = document.createElement('option');
                option.value = 'ungrouped';
                option.textContent = `未分组 (${ungroupedCount})`;
                elements.previewGroupSelect.appendChild(option);
            }
        }

        // 更新预览列表
        function updatePreview() {
            const selectedGroup = elements.previewGroupSelect.value;
            let previewChannels = [];
            
            if (selectedGroup === 'all') {
                previewChannels = [...appData.channels];
            } else if (selectedGroup === 'ungrouped') {
                previewChannels = appData.channels.filter(c => !c.groupId);
            } else {
                previewChannels = appData.channels.filter(c => c.groupId === selectedGroup);
            }
            
            // 按分组和名称排序
            previewChannels.sort((a, b) => {
                // 先按分组排序
                if (a.groupId !== b.groupId) {
                    if (!a.groupId) return 1;
                    if (!b.groupId) return -1;
                    const groupA = appData.groups.find(g => g.id === a.groupId);
                    const groupB = appData.groups.find(g => g.id === b.groupId);
                    return (groupA?.name || '').localeCompare(groupB?.name || '');
                }
                // 再按名称排序
                return a.name.localeCompare(b.name);
            });
            
            renderPreviewList(previewChannels, selectedGroup === 'all' || selectedGroup === 'ungrouped' && appData.groups.length > 0);
        }

        // 渲染预览列表
        function renderPreviewList(channels, showGroupHeaders) {
            elements.previewList.innerHTML = '';
            
            if (channels.length === 0) {
                elements.previewList.innerHTML = `
                    <div class="p-6 text-center text-gray-500">
                        <i class="fa fa-info-circle text-2xl mb-2"></i>
                        <p>没有找到频道</p>
                    </div>
                `;
                return;
            }
            
            let currentGroupId = null;
            
            channels.forEach(channel => {
                // 如果需要显示分组标题且当前频道属于新的分组
                if (showGroupHeaders && channel.groupId !== currentGroupId) {
                    currentGroupId = channel.groupId;
                    
                    const groupHeader = document.createElement('div');
                    groupHeader.className = 'bg-gray-50 p-2 font-medium text-gray-700 border-b';
                    
                    if (currentGroupId) {
                        const group = appData.groups.find(g => g.id === currentGroupId);
                        groupHeader.textContent = group ? group.name : '未知分组';
                    } else {
                        groupHeader.textContent = '未分组';
                    }
                    
                    elements.previewList.appendChild(groupHeader);
                }
                
                const group = appData.groups.find(g => g.id === channel.groupId);
                const groupName = group ? group.name : '未分组';
                
                const previewItem = document.createElement('div');
                previewItem.className = 'p-3 border-b last:border-0 hover:bg-gray-50';
                previewItem.innerHTML = `
                    <div class="grid grid-cols-4 gap-2">
                        <div class="font-medium text-gray-800 truncate">${channel.name}</div>
                        <div class="hidden md:block text-gray-600 text-sm truncate">${groupName}</div>
                        <div class="hidden lg:block text-gray-600 text-xs truncate">${channel.url}</div>
                        <div class="text-center">
                            <button class="text-primary hover:text-primary/80 transition-colors test-play-btn" data-url="${channel.url}">
                                <i class="fa fa-play-circle"></i>
                            </button>
                        </div>
                    </div>
                `;
                elements.previewList.appendChild(previewItem);
            });
            
            // 添加测试播放事件（这里只是模拟，实际播放需要播放器支持）
            document.querySelectorAll('.test-play-btn').forEach(btn => {
                btn.addEventListener('click', (e) => {
                    e.stopPropagation();
                    const url = e.currentTarget.dataset.url;
                    alert(`正在尝试播放: ${url}\n\n实际应用中，这里会调用播放器播放该URL。`);
                });
            });
        }

        // 导出播放列表
        function exportPlaylist() {
            let fileName = elements.outputFileName.value.trim() || 'playlist';
            const isM3U8 = elements.formatM3U8.checked;
            fileName += isM3U8 ? '.m3u8' : '.m3u';
            
            // 构建M3U内容
            let content = isM3U8 ? '#EXTM3U\n' : '#EXTM3U\n';
            const includeGroups = elements.includeGroups.checked;
            
            // 按分组排序
            const channelsByGroup = {};
            const ungroupedChannels = [];
            
            appData.channels.forEach(channel => {
                if (channel.groupId) {
                    if (!channelsByGroup[channel.groupId]) {
                        channelsByGroup[channel.groupId] = [];
                    }
                    channelsByGroup[channel.groupId].push(channel);
                } else {
                    ungroupedChannels.push(channel);
                }
            });
            
            // 添加分组频道
            if (includeGroups) {
                // 按分组名称排序
                const sortedGroupIds = Object.keys(channelsByGroup).sort((a, b) => {
                    const groupA = appData.groups.find(g => g.id === a);
                    const groupB = appData.groups.find(g => g.id === b);
                    return (groupA?.name || '').localeCompare(groupB?.name || '');
                });
                
                sortedGroupIds.forEach(groupId => {
                    const group = appData.groups.find(g => g.id === groupId);
                    if (group) {
                        // 添加分组标记（非标准，但很多播放器支持）
                        content += `#EXTGRP:${group.name}\n`;
                    }
                    
                    // 按名称排序频道
                    channelsByGroup[groupId].sort((a, b) => a.name.localeCompare(b.name))
                        .forEach(channel => {
                            content += `#EXTINF:${channel.duration}${channel.params},${channel.name}\n`;
                            content += `${channel.url}\n`;
                        });
                });
                
                // 添加未分组频道
                if (ungroupedChannels.length > 0) {
                    content += `#EXTGRP:未分组\n`;
                    ungroupedChannels.sort((a, b) => a.name.localeCompare(b.name))
                        .forEach(channel => {
                            content += `#EXTINF:${channel.duration}${channel.params},${channel.name}\n`;
                            content += `${channel.url}\n`;
                        });
                }
            } else {
                // 不包含分组信息，按名称排序所有频道
                [...appData.channels].sort((a, b) => a.name.localeCompare(b.name))
                    .forEach(channel => {
                        content += `#EXTINF:${channel.duration}${channel.params},${channel.name}\n`;
                        content += `${channel.url}\n`;
                    });
            }
            
            // 创建并下载文件
            const blob = new Blob([content], { type: 'application/x-mpegURL' });
            const url = URL.createObjectURL(blob);
            const a = document.createElement('a');
            a.href = url;
            a.download = fileName;
            document.body.appendChild(a);
            a.click();
            document.body.removeChild(a);
            URL.revokeObjectURL(url);
        }

        // 重置应用
        function resetApp() {
            appData.files = [];
            appData.channels = [];
            appData.groups = [];
            appData.selectedChannelIds.clear();
            appData.currentGroupId = null;
            
            elements.fileList.classList.add('hidden');
            elements.selectedFiles.innerHTML = '';
            elements.processBtn.disabled = true;
            
            goToStep(1);
        }

        // 打开帮助模态框
        function openHelpModal() {
            elements.helpModal.classList.remove('hidden');
        }

        // 关闭帮助模态框
        function closeHelpModal() {
            elements.helpModal.classList.add('hidden');
        }

        // 切换主题（简单实现）
        function toggleTheme() {
            const isDark = document.body.classList.toggle('bg-gray-900');
            if (isDark) {
                document.body.classList.add('text-gray-100');
                document.body.classList.remove('bg-gray-50', 'text-gray-800');
                elements.themeToggle.innerHTML = '<i class="fa fa-sun-o"></i>';
                document.querySelectorAll('header, footer').forEach(el => {
                    el.classList.add('bg-gray-800', 'border-gray-700');
                    el.classList.remove('bg-white', 'border-gray-200');
                });
                document.querySelectorAll('.bg-white').forEach(el => {
                    el.classList.add('bg-gray-800');
                    el.classList.remove('bg-white');
                });
                document.querySelectorAll('.text-gray-800').forEach(el => {
                    el.classList.add('text-gray-100');
                    el.classList.remove('text-gray-800');
                });
            } else {
                document.body.classList.add('bg-gray-50', 'text-gray-800');
                document.body.classList.remove('bg-gray-900', 'text-gray-100');
                elements.themeToggle.innerHTML = '<i class="fa fa-moon-o"></i>';
                document.querySelectorAll('header, footer').forEach(el => {
                    el.classList.add('bg-white', 'border-gray-200');
                    el.classList.remove('bg-gray-800', 'border-gray-700');
                });
                document.querySelectorAll('.bg-gray-800').forEach(el => {
                    el.classList.add('bg-white');
                    el.classList.remove('bg-gray-800');
                });
                document.querySelectorAll('.text-gray-100').forEach(el => {
                    el.classList.add('text-gray-800');
                    el.classList.remove('text-gray-100');
                });
            }
        }

        // 初始化应用
        document.addEventListener('DOMContentLoaded', initApp);
    </script>
</body>
</html>
